x86 mca: Be more careful for printk in MCE context
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 29 Jan 2010 06:50:23 +0000 (06:50 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 29 Jan 2010 06:50:23 +0000 (06:50 +0000)
MCE may happen in printk context, and will cause deadlock if we try to
call printk again in MCE context.

A new level(mce_critical) is added to mce_verbosity for printk in mce
context. This level is only for developer that aware of such issue.
In mce_panic, force console unlock.

Singed-off-by: Jiang, Yunhong <yunhong.jiang@intel.com>
xen/arch/x86/cpu/mcheck/mce.c
xen/arch/x86/cpu/mcheck/mce.h
xen/arch/x86/cpu/mcheck/mce_intel.c

index 415e6a0a449514a87005eea676ed871c649fdaab..c1b5983c43031f7728a1bf0743f7d1e131b82db9 100644 (file)
@@ -1605,7 +1605,7 @@ void set_poll_bankmask(struct cpuinfo_x86 *c)
 void mc_panic(char *s)
 {
     is_mc_panic = 1;
-    console_start_sync();
+    console_force_unlock();
     printk("Fatal machine check: %s\n", s);
     printk("\n"
            "****************************************\n"
index 48fdf506d8299d488aaa1e5b33e682f50a523322..6a8c8c85b3b8e65ed59e6bc50d74e3faf3f87a64 100644 (file)
 #include "x86_mca.h"
 #include "mctelem.h"
 
-#define MCE_QUIET 0
-#define MCE_VERBOSE 1
+#define MCE_QUIET       0
+#define MCE_VERBOSE     1
+/* !only for developer debug as printk is unsafe in MCE context */
+#define MCE_CRITICAL    2
 
 extern int mce_verbosity;
 /* Define the default level of machine check related print.
index fe1610d426f37ceca6841928f9eb9056455dc517..e2cd0012dc46932b5a6ef7ad2960e6caf46793ab 100644 (file)
@@ -687,7 +687,7 @@ static void intel_machine_check(struct cpu_user_regs * regs, long error_code)
         }
         atomic_set(&found_error, 1);
 
-        mce_printk(MCE_VERBOSE, "MCE: clear_bank map %lx on CPU%d\n",
+        mce_printk(MCE_CRITICAL, "MCE: clear_bank map %lx on CPU%d\n",
                 *((unsigned long*)clear_bank), smp_processor_id());
         mcheck_mca_clearbanks(clear_bank);
        /* Print MCE error */
@@ -714,13 +714,13 @@ static void intel_machine_check(struct cpu_user_regs * regs, long error_code)
     /* Clear error finding flags after all cpus finishes above judgement */
     mce_barrier_enter(&mce_trap_bar);
     if (atomic_read(&found_error)) {
-        mce_printk(MCE_VERBOSE, "MCE: Choose one CPU "
+        mce_printk(MCE_CRITICAL, "MCE: Choose one CPU "
                        "to clear error finding flag\n ");
         atomic_set(&found_error, 0);
     }
     mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus);
     if ((gstatus & MCG_STATUS_MCIP) != 0) {
-        mce_printk(MCE_VERBOSE, "MCE: Clear MCIP@ last step");
+        mce_printk(MCE_CRITICAL, "MCE: Clear MCIP@ last step");
         mca_wrmsrl(MSR_IA32_MCG_STATUS, gstatus & ~MCG_STATUS_MCIP);
     }
     mce_barrier_exit(&mce_trap_bar);